package com.zwj.spring_study.a01;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 张文接
 * @version 1.0
 * @createTime 2024/5/12 19:56
 */
@Slf4j
public class TestBeanFactory2 {

    public static void main(String[] args) {
        //定义一个BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //定义一个BeanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class)
                .setScope(BeanDefinition.SCOPE_SINGLETON)
                .getBeanDefinition();
        //注册到BeanFactory中
        beanFactory.registerBeanDefinition("config", beanDefinition);
        //注册常用的BeanFactory  后置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        //使用上面添加的BeanPostProcessor
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        //看看初始化完成的Bean2中，是否完成了成员变量Bean1的实例化
//        Bean1 bean1 = beanFactory.getBean(Bean1.class);
//        log.info("bean1 = {}, bean1.bean2 = {}", bean1, bean1.getBean2());
        /*
                  此时发现在Bean2中依赖注入的Bean1没有初始化完成，成员变量bean1 = null;
                  这是因为上面注册的BeanFactory后置处理器没有生效。。。。。
         */
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            log.info(beanDefinitionName);
        }
        Bean1 bean1_1 = beanFactory.getBean(Bean1.class);
        log.info("bean1 = {}, bean1.bean2 = {}", bean1_1, bean1_1.getBean2());
    }


    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    @Getter
    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        @Autowired
        private Bean2 bean2;

        public Bean1() {
            log.info("构造方法 Bean1（）");
        }

    }

    @Getter
    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            log.info("构造方法 Bean2（）");
        }
    }
}
